package com.wsk.api.impl;

import com.wsk.api.bean.User;
import com.wsk.api.bean.UserEnum;
import com.wsk.api.factory.UserFactory;
import com.wsk.api.service.ManagerUser;
import com.wsk.api.utils.UserUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @DESCRIPTION :
 * @AUTHOR : WuShukai1103
 * @TIME : 2017/12/9  20:13
 */
//@Service
//@ImportResource(locations = {"classpath:provider.xml"})
public class ManagerUserImpl implements ManagerUser {

    private static final String NAME = "name";
    private static final String PASSWORD = "password";
    private static final String USERENUM = "userenum";

    @Autowired
    private UserFactory userFactory;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Override
    public boolean save(User user) {
        if (!UserUtils.isEmpty(user)) {
            try {
//                redisTemplate.multi();
                redisTemplate.opsForValue().set("String_" + user.getId(), user.getId());
                redisTemplate.opsForHash().put( user.getId(), NAME, user.getName());
                redisTemplate.opsForHash().put( user.getId(), PASSWORD, user.getPassword());
                redisTemplate.opsForHash().put( user.getId(), USERENUM, user.getUserEnum().toString());
                redisTemplate.expire("String_" + user.getId(), 45, TimeUnit.MINUTES);
                redisTemplate.expire( user.getId(), 5, TimeUnit.MINUTES);
//                redisTemplate.exec();
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
        return false;
    }

    @Override
    public boolean delete(User user) {
        if (!UserUtils.isEmpty(user)) {
            try {
//                redisTemplate.multi();
                redisTemplate.delete( user.getId());
                redisTemplate.delete("String_" + user.getId());
//                redisTemplate.exec();
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
        return true;
    }

    @Override
    public User findById(String id) {
        try {
            Map<Object, Object> map = redisTemplate.opsForHash().entries(id);
            if (map != null) {
                UserEnum userEnum = Enum.valueOf(UserEnum.class, (String) map.get(USERENUM));
                User user = userFactory.getUser(userEnum);
                user.setId(id);
                user.setName((String) map.get(NAME));
                user.setUserEnum(userEnum);
                user.setPassword((String) map.get(PASSWORD));
                return user;
            }
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public List<User> users() {
        List<User> result = new ArrayList<>();
        try {
            Set<String> set = redisTemplate.keys("*");
            List<String> list = set.stream().filter(l -> !l.contains("String_")).collect(Collectors.toList());
            for (String s : list) {
//                redisTemplate.expire(s, 1, TimeUnit.SECONDS);
                Map<Object, Object> map = redisTemplate.opsForHash().entries(s);
                String e = (String) map.get(USERENUM);
                if (null != e) {
                    UserEnum userEnum = Enum.valueOf(UserEnum.class,e );
                    User user = userFactory.getUser(userEnum);
                    user.setName((String) map.get(NAME));
                    user.setUserEnum(userEnum);
                    user.setId(s);
                    user.setPassword((String) map.get(PASSWORD));
                    result.add(user);
                }
            }
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public boolean update(User user) {
        if (!UserUtils.isEmpty(user)) {
            try {
//                redisTemplate.multi();
                if (StringUtils.isNotBlank(user.getName())) {
                    redisTemplate.opsForHash().put(user.getId(), NAME, user.getName());
                }
                if (StringUtils.isNotBlank(user.getPassword())) {
                    redisTemplate.opsForHash().put(user.getId(), PASSWORD, user.getPassword());
                }
                if (StringUtils.isNotBlank(user.getUserEnum().toString())) {
                    redisTemplate.opsForHash().put(user.getId(), USERENUM, user.getUserEnum().toString());
                }
//                redisTemplate.exec();
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
        return true;
    }
}
